from urlparse import urlparse
import logging

from google.appengine.api import users

from app import models
from app.attrdata import AttrData

class Link:
	def __init__(self, url, owner = None, link_data = '', tags = None, attr_data = '', 
				key = None):
		self.url = url
		self.owner = owner if owner is not None else users.User("none")
		self.domain, self.superdomains = self.__extract_domain()
		self.tags = set(tags) if tags is not None else set()
		self.link_data = link_data
		self.attr_data = attr_data
		self.key = key
		#user, timestamp?

	def __extract_domain(self):
		parse_result = urlparse(self.url)
		domain = parse_result.netloc

		port = parse_result.port
		if port is not None:
			logging.debug(port)
			# remove trailing port designation ":XXXX"
			domain = domain.rsplit(':', 1)[-2]

		superdomains = list()
		superdomain = ''
		for word in domain.split('.')[::-1]:
			# ['com', 'example', 'www']
			if superdomain == '':
				superdomain = word
			else:
				superdomain = word + '.' + superdomain
			# ['com', 'example.com', 'www.example.com']
			superdomains.append(superdomain)

		return domain, superdomains

	def put(self):
		link = models.Link(
						url = self.url,
						owner = self.owner,
						domain = self.domain,
						superdomains = self.superdomains,
						tags = list(self.tags), 
						link_data = self.link_data,
						attr_data = self.attr_data,
						key = self.key,
						)
		link.put()
		self.key = link.key()

	def delete(self):
		models.Link(key = self.key).delete()

	def add_tag(self, tag):
		self.tags.add(tag)

	def add_tags(self, *tags):
		for tag in tags:
			self.add_tag(tag)

	def delete_tag(self, tag):
		try:
			self.tags.remove(tag)
		except (KeyError, ValueError): # ValueError for list, KeyError for set
			logging.warning("Link.delete_tag(): trying to delete a nonexistent tag '%s'" % tag)

	def delete_tags(self, *tags):
		"""Delete one or more tags"""
		for tag in tags:
			self.delete_tag(tag)

	def get_tags(self):
		return self.tags

	def set_attribute(self, **attribute):
		self.set_attributes(**attribute)

	def set_attributes(self, **attributes):
		attribs = AttrData(self.attr_data)
		for key in attributes.keys():
			attribs.set_attribute(name=key, value=attributes[key])
		self.attr_data = attribs.to_string()

	def add_attribute(self, **attribute):
		self.add_attributes(**attribute)

	def add_attributes(self, **attributes):
		# raise if exists?
		self.set_attributes(**attributes)

	def delete_attribute(self, name):
		attribs = AttrData(self.attr_data)
		attribs.delete_attribute(name)
		self.attr_data = attribs.to_string()

	def get_attribute(self, name):
		return AttrData(self.attr_data).get_attribute(name)

